package com.itheima.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.common.entity.PageResult;
import com.itheima.common.entity.QueryPageBean;
import com.itheima.common.entity.Result;
import com.itheima.dto.HotSetmealDto;
import com.itheima.file.MinioFileUtil;
import com.itheima.mapper.SetmealCheckGroupDao;
import com.itheima.mapper.SetmealDao;
import com.itheima.pojo.Setmeal;
import com.itheima.pojo.SetmealReport;
import com.itheima.service.ISetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class ISetmealServiceImpl implements ISetmealService {

    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private SetmealCheckGroupDao setmealCheckGroupDao;

    @Autowired
    private MinioFileUtil minioFileUtil;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 添加套餐
     *
     * @param checkgroupIds
     * @param setmeal
     * @return
     */
    @Override
    @Transactional
    public Result add(String checkgroupIds, Setmeal setmeal) {
        if (checkgroupIds == null || checkgroupIds.equals("")) {
            return Result.of(false, "参数有误!", null);
        }

        String filePath = setmeal.getImg();
        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);

        //检查图片是否已经上传至minio
        Boolean exist = redisTemplate.opsForSet().isMember("uploadImgUrl", fileName);

        if (Boolean.FALSE.equals(exist)) {
            return Result.of(false, "图片信息已失效!", null);
        }


        List<String> ids = Arrays.asList(checkgroupIds.split(","));


        //添加套餐
        int affect = setmealDao.add(setmeal);
        if (affect == 0) {
            return Result.of(false, "新增套餐失败!", null);
        }

        //创建检查组和套餐之间关系
        setmealCheckGroupDao.addRelation(ids, setmeal.getId());

        //将图片保存至redis
        redisTemplate.opsForSet().add("databaseImgUrl", fileName);

        //向redis存入添加的套餐id 用户端服务检测后更新静态页面
        redisTemplate.opsForValue().append("setmeal_Add_Update", setmeal.getId().toString() + ",");

        return Result.of(true, "新增套餐成功", null);
    }

    /**
     * 编辑套餐
     *
     * @param checkgroupIds
     * @param setmeal
     * @return
     */
    @Override
    @Transactional
    public Result edit(String checkgroupIds, Setmeal setmeal) {
        if (checkgroupIds == null || checkgroupIds.equals("") || setmeal.getId() == null) {
            return Result.of(false, "参数有误!", null);
        }

        List<String> ids = Arrays.asList(checkgroupIds.split(","));

        String filePath = setmeal.getImg();
        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);

        //检查图片是否存在redis中，及代表图片被修改了
        Boolean exist = redisTemplate.opsForSet().isMember("uploadImgUrl", fileName);

        Setmeal oldSetmeal = setmealDao.findById(setmeal.getId().toString());
        String oldFileName = oldSetmeal.getImg().substring(filePath.lastIndexOf("/") + 1);

        //不存在证明图片未更改或已失效，使用原有图片
        if (Boolean.FALSE.equals(exist)) {
            setmeal.setImg(oldSetmeal.getImg());
        }

        //更新套餐信息
        int affect = setmealDao.edit(setmeal);

        if (affect == 0) {
            return Result.of(false, "修改套餐失败!", null);
        }

        //删除套餐和检查组原有关系
        setmealCheckGroupDao.deleteRelation(setmeal.getId());

        //重新建立套餐和检查组关系
        setmealCheckGroupDao.addRelation(ids, setmeal.getId());

        //存在,并且名字不同证明图片更改了
        if (Boolean.TRUE.equals(exist) && !fileName.equals(oldFileName)) {
            minioFileUtil.remove(oldFileName);
            //将图片保存至redis
            redisTemplate.opsForSet().add("databaseImgUrl", fileName);
        }

        //向redis存入添加的套餐id 用户端服务检测后更新静态页面
        redisTemplate.opsForValue().append("setmeal_Add_Update", setmeal.getId().toString() + ",");

        return Result.of(true, "修改套餐成功", null);
    }

    /**
     * 根据id查询套餐
     *
     * @param id
     * @return
     */
    @Override
    public Result findById(String id) {
        Setmeal setmeal = setmealDao.findById(id);
        return Result.of(true, "查询套餐成功", setmeal);
    }

    /**
     * 分页查询套餐
     *
     * @param query
     * @return
     */
    @Override
    public PageResult<Setmeal> findPage(QueryPageBean query) {
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());

        List<Setmeal> setmealList = setmealDao.findByCondition(query.getQueryString());

        PageInfo<Setmeal> pageInfo = new PageInfo<>(setmealList);

        return new PageResult<>(pageInfo.getTotal(), setmealList);
    }

    /**
     * 文件上传
     *
     * @param imgFile
     * @return
     */
    @Override
    public Result upload(MultipartFile imgFile) {
        String filePath = "";
        try {
            filePath = minioFileUtil.uploadFile(imgFile);
            //将路径存入redis中
            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
            redisTemplate.opsForSet().add("uploadImgUrl", fileName);

            return Result.of(true, "图片上传成功", filePath);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.of(false, "图片上传失败", filePath);
        }

    }

    /**
     * 获取套餐报告
     *
     * @return
     */
    @Override
    public List<SetmealReport> getSetmealReport() {

        return setmealDao.getSetmealReport();
    }

    /**
     * 获取热门套餐
     *
     * @return
     */
    @Override
    public List<HotSetmealDto> getHotSetmeals() {
        List<SetmealReport> setmealReport = setmealDao.getSetmealReport();
        Integer total = 0;
        double ratioSum = 0;
        for (SetmealReport report : setmealReport) {
            total += report.getValue();
        }
        List<HotSetmealDto> hotSetmealDtos = new ArrayList<>(setmealReport.size());
        for (int i = 0; i < setmealReport.size(); i++) {
            SetmealReport report = setmealReport.get(i);
            HotSetmealDto hotSetmealDto = new HotSetmealDto();

            hotSetmealDto.setName(report.getName());
            hotSetmealDto.setSetmeal_count(report.getValue());
            if (i == setmealReport.size() - 1) {
                BigDecimal bd = new BigDecimal(1 - ratioSum);
                bd = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
                hotSetmealDto.setProportion(bd.doubleValue());
            } else {
                BigDecimal bd = new BigDecimal((double) report.getValue() / total);
                bd = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
                hotSetmealDto.setProportion(bd.doubleValue());
                ratioSum += bd.doubleValue();
            }
            hotSetmealDtos.add(hotSetmealDto);
        }
      /*  for (SetmealReport report : setmealReport) {
            HotSetmealDto hotSetmealDto = new HotSetmealDto();
            hotSetmealDto.setName(report.getName());
            hotSetmealDto.setSetmeal_count(report.getValue());
            BigDecimal bd = new BigDecimal((double) report.getValue() / total);
            bd = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
            hotSetmealDto.setProportion(bd.doubleValue());
            hotSetmealDtos.add(hotSetmealDto);
        }*/
        return hotSetmealDtos;
    }
}
